#######################################################################
# Makefile for python test-suite
#######################################################################

ifneq (,$(PY2))
  PYTHON = @PYTHON@
else
  PYTHON = @PYTHON3@
endif

LANGUAGE     = python
PYFLAGS      = -Werror
SCRIPTSUFFIX = _runme.py
PY_VER_3_DIGIT    = @PY_VER_3_DIGIT@
PYCODESTYLE       = @PYCODESTYLE@
PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,E741,W291,W391

HAVE_CXX11   = @HAVE_CXX11@
HAVE_CXX14   = @HAVE_CXX14@
HAVE_CXX17   = @HAVE_CXX17@
HAVE_CXX20   = @HAVE_CXX20@
srcdir       = @srcdir@
top_srcdir   = @top_srcdir@
top_builddir = @top_builddir@

FAILING_CPP_TESTS = \
	cpp17_map_no_default_ctor \

ifneq (,$(PY2))
# std_string_view.i is not implemented for Python2 so don't try to run tests needing it.
FAILING_CPP_TESTS += \
	cpp17_director_string_view \
	cpp17_string_view \

endif

CPP_TEST_CASES += \
	callback \
	complextest \
	director_guard \
	director_stl \
	director_wstring \
	file_test \
	iadd \
	implicittest \
	inplaceadd \
	input \
	li_cstring \
	li_cwstring \
	li_factory \
	li_implicit \
	li_std_containers_int \
	li_std_list \
	li_std_map_member \
	li_std_multimap \
	li_std_pair_extra \
	li_std_set \
	li_std_stream \
	li_std_string_extra \
	li_std_vectora \
	li_std_vector_extra \
	li_std_wstream \
	li_std_wstring_inherit \
	primitive_types \
	python_abstractbase \
	python_annotations_c \
	python_annotations_variable_c \
	python_append \
	python_builtin \
	python_destructor_exception \
	python_director \
	python_docstring \
	python_extranative \
	python_flatstaticmethod \
	python_moduleimport \
	python_overload_simple_cast \
	python_pickle \
	python_pythoncode \
	python_richcompare \
	python_strict_unicode \
	python_threads \
	python_typemap_macro \
	python_various \
	simutry \
	std_containers \
	swigobject \
	template_matrix \

#	director_profile

ifeq (,$(PY_ABI_VER))
PY_ABI_311:=1
else
PY_ABI_VER_INTEGER:=$(shell printf "%d%02d" $(subst ., ,$(PY_ABI_VER)))
PY_ABI_311:=$(shell test $(PY_ABI_VER_INTEGER) -ge 311 && echo "1")
endif

# Test requiring python-3.11 minimum if using Py_LIMITED_API
ifeq (1,$(PY_ABI_311))
CPP_TEST_CASES += pyabi311_bufferinterface
endif

# Test requiring python-3.11 minimum if using Py_LIMITED_API if and only if python>=3.13
ifeq (1,$(PY_ABI_311))
CPP_TEST_CASES += python_pybuffer
else
PY_313:=$(shell test $(PY_VER_3_DIGIT) -ge 313 && echo "1")
ifeq (,$(PY_313))
CPP_TEST_CASES += python_pybuffer
endif
endif

CPP11_TEST_CASES = \
	cpp11_hash_tables \
	cpp11_shared_ptr_const \
	cpp11_shared_ptr_crtp_upcast \
	cpp11_shared_ptr_nullptr_in_containers \
	cpp11_shared_ptr_overload \
	cpp11_shared_ptr_template_upcast \
	cpp11_shared_ptr_upcast \
	cpp11_std_unordered_map \
	cpp11_std_unordered_multimap \
	cpp11_std_unordered_multiset \
	cpp11_std_unordered_set \

CPP17_TEST_CASES = \
	cpp17_std_filesystem

C_TEST_CASES += \
	ccomplextest \
	file_test \
	li_cstring \
	li_cwstring \
	python_nondynamic \
	python_varargs_typemap \
	python_weakref \

MULTI_CPP_TEST_CASES += \
	import_callback \
	python_runtime_data \

include $(srcdir)/../common.mk

# Overridden variables here
LIBS         = -L.
VALGRIND_OPT += --suppressions=pythonswig.supp

# Ensure testsuite remains free from SWIG warnings.
SWIGOPT += -Werror

# Custom tests - tests with additional commandline options
python_flatstaticmethod.cpptest: SWIGOPT += -flatstaticmethod

# Make sure just python_runtime_data_builtin.i uses the -builtin option. Note: does not use python_runtime_data.list for all steps.
# PY_ABI_VER is unset for python_runtime_data_builtin because stable ABI is not supported by builtin
python_runtime_data.multicpptest: override SWIG_FEATURES := $(filter-out -builtin,$(SWIG_FEATURES))
python_runtime_data.multicpptest: override SWIGOPT := $(filter-out -builtin,$(SWIGOPT))
python_runtime_data.multicpptest: swig_and_compile_multi_cpp = \
	$(call swig_and_compile_cpp_helper,python_runtime_data_builtin,'$(SWIGOPT) -builtin' PY_ABI_VER=) && \
	$(call swig_and_compile_cpp_helper,python_runtime_data_nobuiltin,'$(SWIGOPT)')

# Rules for the different types of tests
%.cpptest:
	$(setup)
	+$(swig_and_compile_cpp)
	$(check_pep8)
	$(run_testcase)

%.ctest:
	$(setup)
	+$(swig_and_compile_c)
	$(check_pep8)
	$(run_testcase)

%.multicpptest:
	$(setup)
	+$(swig_and_compile_multi_cpp)
	$(check_pep8_multi_cpp)
	$(run_testcase)


# Python code style checking
ifneq (,$(PYCODESTYLE))
check_pep8 = $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(SCRIPTPREFIX)$*.py

check_pep8_multi_cpp = \
	for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
	  $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $$f.py; \
	done
endif

# Runs the testcase. A testcase is only run if
# a file is found which has _runme.py appended after the testcase name.
run_testcase = \
	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PYTHONPATH=.:$(srcdir):$$PYTHONPATH $(RUNTOOL) $(PYTHON) $(PYFLAGS) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
	fi

# Clean: remove the generated .py file
%.clean:
	@rm -f $*.py

clean:
	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' python_clean
	rm -f clientdata_prop_a.py clientdata_prop_b.py import_stl_a.py import_stl_b.py
	rm -f ../hugemod.h ../hugemod_a.i ../hugemod_b.i hugemod_a.py hugemod_b.py $(hugemod_runme)
	rm -f imports_a.py imports_b.py mod_a.py mod_b.py multi_import_a.py
	rm -f multi_import_b.py multi_import_d.py packageoption_a.py packageoption_b.py packageoption_c.py
	rm -f template_typedef_cplx2.py python_runtime_data_builtin.py python_runtime_data_nobuiltin.py
	rm -f import_callback_x.py import_callback_y.py

hugemod_runme = $(SCRIPTPREFIX)hugemod$(SCRIPTSUFFIX)

# Note: hugemod not run by default
hugemod:
	perl hugemod.pl $(hugemod_runme)
	$(MAKE) hugemod_a.cpptest
	$(MAKE) hugemod_b.cpptest
	time $(PYTHON) $(PYFLAGS) $(hugemod_runme)
	time $(PYTHON) $(PYFLAGS) $(hugemod_runme)
